/**
  ******************************************************************************
  * @file           : auto_decision_make_task.cpp
  * @author         : Tessia
  * @brief          : None
  * @attention      : None
  * @date           : 2024/3/14
  ******************************************************************************
  */



#include "auto_decision_make_task.h"

extern match_type matchType;
extern coo_info cooInfo; //目标车体坐标
extern AimAutoStruct AimAutoData;
extern radar_info radarInfo;
extern state_transform debug_state_table[STATE_NUM][EVENT_NUM];
extern state_transform RMUL_state_table[STATE_NUM][EVENT_NUM];
extern state_transform RMUC_state_table[STATE_NUM][EVENT_NUM];
extern rc_device_t g_rc;
extern osSemaphoreId_t StateMachineBinarySemHandle;
extern judge_info_0 judgeInfo0;
extern judge_info_1 judgeInfo1;
extern judge_info_2 judgeInfo2;
extern uint8_t VisionControlFlag;
extern twins_receive_info twins_receive;
extern enemy_coo enemyCoo;
extern uint16_t restored_HP;
extern uint16_t enemy_HP[12];
extern VisionDataStruct VisionReceive;
extern uint8_t robot_data_update;
extern judge_HP_info judgeHpInfo;
extern float out_patrol_zone_time;
extern sentry_decision_info sentry_decision;
extern uint8_t exchange_ammo_request;              //兑换发弹量请求
extern uint8_t remote_exchange_ammo_request;       //远程兑换发弹量请求
extern uint8_t armor_number;
extern uint8_t armor_number_no_zero;
extern uint8_t enemy_aim_enable[12];
extern int32_t out_patrol_zone_time_ms;
extern uint16_t outpost_fire_cnt;
extern uint16_t healing_spot_ammo_accumulation;
extern enemy_robot_coo radar_station_data[8];
extern aerial_operator_data aerialOperatorData;
extern uint16_t attack_outpost_time;
extern float pursuit_time;


/******************     以下只适用于约束防守状态下的决策    *******************/
uint8_t constrained_defense_state_lock = 0; //约束防守状态锁
uint8_t constrained_defense_state_last = 0;
uint8_t constrained_defense_state = 0;
uint8_t hp_low = 0;
uint8_t hp_not_full = 0;
uint8_t hp_full = 0;
uint8_t ammunition_depleted = 0;            //弹丸耗尽
uint8_t time_short = 0;                     //区外时间小于32s
uint8_t insufficient_gold = 0;              //金币贫乏，小于550
uint8_t late_stage = 0;                     //后期阶段，指后三分钟
uint8_t on_the_way_healing = 0;
uint8_t on_the_way_R2 = 0;
uint8_t on_the_way_R3 = 0;
uint8_t on_the_way_R4 = 0;
uint8_t on_the_way_base = 0;
uint8_t switch_base_patrol_zone = 0;
uint8_t switch_R3_patrol_zone = 0;
uint8_t switch_R2_patrol_zone = 0;





uint8_t outpost_be_destroyed = 0;  //前哨站被击毁标志位
uint8_t is_occupy_healing_spot_last = 0;

uint8_t supply_state = 0;
uint8_t supply_state_last = 0;
uint8_t dead_once = 0;
uint32_t be_hit_flag = 0;
uint8_t is_need_high_speed = 0;
uint8_t healed_once = 0;
uint8_t sentry_destination = 0;     //0表示未知

sentry_state normal_state = standby;
sentry_state normal_state_last = standby;
sentry_event normal_event = none;

//以蓝方为标准，红方在代码中会自动处理
point2f debugLocation[LOCATION_NUM] = {
        {5,5},         //最远点
        {2.5,2.5},     //中心点
        {1,1},         //右下角
        {4,1},         //右上角
        {1,4},         //左下角
        {4,4},         //左上角
        {2.5,1},       //出生点
        ///下面三个暂时不用
        {1,1},         //激进点
        {1,1},         //保守点
        {1,1},         //回血点
};


//以红方为标准，蓝方在代码中会自动处理
point2f RMUL_location[LOCATION_NUM] = {
        {12,8},         //最远点
        {6,4},          //中心点
        {4,1},          //右下角
        {10,1},         //右上角
        {8,7},          //左下角
        {2,7},          //左上角
        {3.1,3.5},      //出生点
        {8,1},          //激进点
        {7,6.5},        //保守点
        {0.75,7},       //回血点
};

//国赛
point2f RMUC_location[LOCATION_NUM] = {
        {18.02,4.15},            //最远点
        {14,7.5},           //中心点
        {1,1},              //右下角
        {1,1},              //右上角
        {1,1},              //左下角
        {1,1},              //左上角
        {0,0},              //出生点
        {0,0},              //激进点
        {0,0},              //保守点
        {-4.65,-4.11},              //回血点
        {14.12,3.68},          //敌方汇进点
        {16.74,0.67},         //敌方基地口
        {12.04,-4.49},         //敌方R1坡口
        {12.47,4.87},         //敌方前哨站打击点
        {-0.83,0.5},        //我方基地巡逻区
        {4.53,5.63},        //我方R2巡逻区
        {0.836,6.58},        //我方R3巡逻区
        {0.836,6.58},        //我方R4巡逻区
        {4.99,-1.68},          //我方前哨站保卫区
        {1.62,7.02},         //我方桥洞入口
        {-3.94,4.40},         //我方R1坡口

};

point2f base_patrol_zone[3] = {
        {-0.83,0.5},
        {-0.15,4.37},
        {-1.65,2.44}
};

point2f R2_patrol_zone[2] = {
        {4.53,5.63},
        {3.49,4.05}
};

point2f R3_patrol_zone[3] = {
        {0.836,6.58},
        {0.221,5.58},
        {0.221,5.58}
};

////彩虹楼
//point2f RMUC_location[LOCATION_NUM] = {
//        {20,20},            //最远点
//        {1,1},           //中心点
//        {1,1},              //右下角
//        {1,1},              //右上角
//        {1,1},              //左下角
//        {1,1},              //左上角
//        {0,0},              //出生点
//        {0,0},              //激进点
//        {0,0},              //保守点
//        {-2.22,1.23},              //回血点
//        {0.43,4.26},          //敌方汇进点
//        {0.33,-1.11},         //敌方基地口
//        {0.33,-1.11},         //敌方R1坡口
//        {0.35,0.7},         //敌方前哨站打击点
//        {-1.07,0.67},        //我方基地巡逻区
//        {-1.07,0.35},        //我方R2巡逻区
//        {-1.07,0.35},        //我方R3巡逻区
//        {-1.07,0.35},        //我方R4巡逻区
//        {0.43,4.26},          //我方前哨站保卫区
//        {0.33,-1.11},         //我方桥洞入口
//        {0.33,-1.11},         //我方R1坡口
//
//};
//
//point2f base_patrol_zone[3] = {
//        {-1.07,0.67},
//        {-1.07,0.67},
//        {-1.07,0.67}
//};
//
//point2f R2_patrol_zone[2] = {
//        {-1.07,0.35},
//        {-1.07,0.35}
//};
//
//point2f R3_patrol_zone[2] = {
//        {-1.07,0.35},
//        {-1.07,0.35},
//};

static sentry_state_machine state_machine(RMUC_state_table, &StateMachineBinarySemHandle);


bool is_target_point_reach(){
    if((abs(cooInfo.coo_x - radarInfo.coo_x_current) < 0.2 && abs(cooInfo.coo_y - radarInfo.coo_y_current) < 0.2)
    || (abs(radarInfo.coo_x_correction - radarInfo.coo_x_current) < 0.2 && abs(radarInfo.coo_y_correction - radarInfo.coo_y_current) < 0.2) && radarInfo.can_not_go == 1){
        return true;
    }else{
        return false;
    }
}

void go_to_target(float target_x, float target_y){
    cooInfo.stop = 0;
    cooInfo.coo_x = target_x;
    cooInfo.coo_y = target_y;
    is_need_high_speed = is_target_point_reach() ? 0 : 1;
}

void go_home(point2f *map_type){
    cooInfo.stop = 0;
    cooInfo.coo_x = map_type[healing_point].x;
    cooInfo.coo_y = map_type[healing_point].y;
    sentry_destination = healing_point;
    is_need_high_speed = is_target_point_reach() ? 0 : 1;
}

void chassis_stop(){
    cooInfo.stop = 1;
}

void chassis_run(){
    cooInfo.stop = 0;
}

bool is_state_change_once(){
    osStatus_t status = osSemaphoreAcquire(StateMachineBinarySemHandle, 0);
    if(status == osOK){
        return true;
    }else{
        return false;
    }
}

float distance_between_double_coo(float x_1, float y_1, float x_2, float y_2){
    return pow(pow(x_1 - x_2,2) + pow(y_1 - y_2,2),0.5);
}

float distance_to_sentry(float x, float y){
    return pow(pow(x - radarInfo.coo_x_current,2) + pow(y - radarInfo.coo_y_current,2),0.5);
}

float distance_enemy = 0;
void go_attack_enemy() {
    cooInfo.stop = 0;
    float target_cycle_distance = 0;
    distance_enemy = distance_between_double_coo(enemyCoo.x, enemyCoo.y, radarInfo.coo_x_current, radarInfo.coo_y_current);
    target_cycle_distance = distance_enemy - ATTACK_DISTANCE;
    cooInfo.coo_x = radarInfo.coo_x_current + cos(deg2rad(enemyCoo.alpha_to_sentry)) * target_cycle_distance;
    cooInfo.coo_y = radarInfo.coo_y_current + sin(deg2rad(enemyCoo.alpha_to_sentry)) * target_cycle_distance;
    is_need_high_speed = is_target_point_reach() ? 0 : 1;
    sentry_destination = 0;
}

void location_init(){
    if(judgeInfo1.is_blue == 1){
        for(int i=1;i < LOCATION_NUM;i++){
            RMUL_location[i].x = RMUL_location[0].x - RMUL_location[i].x;
            RMUL_location[i].y = RMUL_location[0].y - RMUL_location[i].y;
        }
        RMUL_location[healing_point].x = 11.5;
        RMUL_location[healing_point].y = 1;
        RMUL_location[radical_point].x = 4;
        RMUL_location[radical_point].y = 6.75;
        RMUL_location[conservative_point].x = 7;
        RMUL_location[conservative_point].y = 1.3;
        RMUL_location[initial_point].x = 7;
        RMUL_location[initial_point].y = 6;
    }else{
        for(int i=1;i < LOCATION_NUM;i++){
            debugLocation[i].x = debugLocation[0].x - debugLocation[i].x;
            debugLocation[i].y = debugLocation[0].y - debugLocation[i].y;
        }
    }
}

point2f closest_coo_to_target(float target_x, float target_y, const point2f *location_array, uint16_t array_length){
    uint16_t array_i = 0;
    uint16_t closest_i = 0;
    for(array_i = 1;array_i < array_length;array_i ++){
        closest_i = distance_between_double_coo(target_x, target_y, (location_array + array_i)->x, (location_array + array_i)->y)
                    < distance_between_double_coo(target_x, target_y, (location_array + closest_i)->x, (location_array + closest_i)->y)
                    ? array_i : closest_i;
    }
    return(*(location_array + closest_i));
}

/**
 * @param patrol_location
 * 该函数只适合约束防守状态时使用
 */
void go_to_constrained_zone(location patrol_location){
    switch(patrol_location){
        case healing_point:
            go_to_target(RMUC_location[healing_point].x, RMUC_location[healing_point].y);
            on_the_way_healing = 1;
            on_the_way_R2 = 0;
            on_the_way_R3 = 0;
            on_the_way_R4 = 0;
            on_the_way_base = 0;
            sentry_destination = healing_point;

            break;
        case our_base_patrol_zone:
            switch (switch_base_patrol_zone) {
                case 0:
                    go_to_target(base_patrol_zone[0].x, base_patrol_zone[0].y);
                    if(is_target_point_reach()){
                        switch_base_patrol_zone = 1;
                    }
                    break;
                case 1:
                    go_to_target(base_patrol_zone[1].x, base_patrol_zone[1].y);
                    if(is_target_point_reach()){
                        switch_base_patrol_zone = 2;
                    }
                    break;
                case 2:
                    go_to_target(base_patrol_zone[2].x, base_patrol_zone[2].y);
                    if(is_target_point_reach()){
                        switch_base_patrol_zone = 0;
                    }
                    break;
                default:
                    go_to_target(base_patrol_zone[0].x, base_patrol_zone[0].y);
                    break;
            }
            on_the_way_healing = 0;
            on_the_way_R2 = 0;
            on_the_way_R3 = 0;
            on_the_way_R4 = 0;
            on_the_way_base = 1;
            sentry_destination = our_base_patrol_zone;

            break;
        case our_R2_patrol_zone:        //环高
            switch (switch_R2_patrol_zone) {
                case 0:
                    go_to_target(R2_patrol_zone[0].x, R2_patrol_zone[0].y);
                    if(is_target_point_reach()){
                        switch_R2_patrol_zone = 1;
                    }
                    break;
                case 1:
                    go_to_target(R2_patrol_zone[1].x, R2_patrol_zone[1].y);
                    if(is_target_point_reach()){
                        switch_R2_patrol_zone = 0;
                    }
                    break;
                default:
                    go_to_target(R2_patrol_zone[0].x, R2_patrol_zone[0].y);
                    break;
            }
            on_the_way_healing = 0;
            on_the_way_R2 = 1;
            on_the_way_R3 = 0;
            on_the_way_R4 = 0;
            on_the_way_base = 0;
            sentry_destination = our_R2_patrol_zone;

            break;
        case our_R3_patrol_zone:        //T高，即英雄狙击点位
            switch (switch_R3_patrol_zone) {
                case 0:
                    go_to_target(R3_patrol_zone[0].x, R3_patrol_zone[0].y);
                    if(is_target_point_reach()){
                        switch_R3_patrol_zone = 1;
                    }
                    break;
                case 1:
                    go_to_target(R3_patrol_zone[1].x, R3_patrol_zone[1].y);
                    if(is_target_point_reach()){
                        switch_R3_patrol_zone = 2;
                    }
                    break;
                case 2:
                    go_to_target(R3_patrol_zone[2].x, R3_patrol_zone[2].y);
                    if(is_target_point_reach()){
                        switch_R3_patrol_zone = 0;
                    }
                    break;
                default:
                    go_to_target(R3_patrol_zone[0].x, R3_patrol_zone[0].y);
                    break;
            }
            on_the_way_healing = 0;
            on_the_way_R2 = 0;
            on_the_way_R3 = 1;
            on_the_way_R4 = 0;
            on_the_way_base = 0;
            sentry_destination = our_R3_patrol_zone;

            break;
        case our_R4_patrol_zone:        //打符点
            go_to_target(RMUC_location[our_R4_patrol_zone].x, RMUC_location[our_R4_patrol_zone].y);

            on_the_way_healing = 0;
            on_the_way_R2 = 0;
            on_the_way_R3 = 0;
            on_the_way_R4 = 1;
            on_the_way_base = 0;
            sentry_destination = our_R4_patrol_zone;

            break;
    }
}

void evaluate_and_return_from_supply_state(){
    if(dead_once == 0){
        state_machine.go_to_specified_state(patrol);
    }else{      //已死亡一次
        state_machine.go_to_specified_state(free_defense);
    }
}


void judge_event_happened_task(void *argument){
    /***********      这里放置可能需要的变量      *********/
    uint8_t game_progress_last = judgeInfo0.game_progress;
    bool g_rc_is_lost_last = g_rc.is_lost;
    uint8_t VisionControlFlagLast = VisionControlFlag;
    uint8_t left_is_target_detected_last = twins_receive.is_target_detected;
    uint8_t be_hit_last = judgeInfo0.be_hit;
    uint8_t mains_power_shooter_output_last = judgeInfo0.mains_power_shooter_output;
    uint16_t last_hp = judgeInfo0.current_HP;
    uint16_t restored_HP_last = restored_HP;
    uint8_t sw_l_last = RC_SW_NONE;
    uint16_t our_outpost_HP_last = judgeHpInfo.our_outpost_HP;
    uint16_t stage_remain_time_last = judgeInfo0.stage_remain_time;
    uint16_t projectile_allowance_17mm_last = judgeInfo2.projectile_allowance_17mm;
    uint16_t enemy_HP_last[12] = {};
    uint8_t radar_is_reliable_last[8] = {};
    uint8_t cmd_keyboard_last = 0;

    for(;;){

        /***********      比赛开始      *********/
        if(judgeInfo0.game_progress == during_the_match && game_progress_last == countdown_stage){
            state_machine.event_happen(match_begin);
            sentry_decision.remote_exchange_ammo_request_count = 0;
            sentry_decision.remote_exchange_health_request_count = 0;
            sentry_decision.exchange_ammo_amount = 0;
            enemy_aim_enable[engineer] = 0;
            enemy_aim_enable[sentry] = 0;
            out_patrol_zone_time_ms = 90000;
            out_patrol_zone_time = 90;
            healing_spot_ammo_accumulation = 0;
        }

        /***********      关自动模式      *********/
        if(((g_rc.rc_info.sw.sw_l == RC_SW_UP && sw_l_last == RC_SW_MID)) && g_rc.rc_info.sw.sw_r == RC_SW_UP){
            state_machine.event_happen(turn_off_auto);
        }

        /***********      开自动模式      *********/
        if(g_rc.is_lost == 0 && g_rc.rc_info.sw.sw_r == RC_SW_UP && (g_rc.rc_info.sw.sw_l == RC_SW_MID && sw_l_last == RC_SW_UP)){
            state_machine.event_happen(turn_on_auto);
        }

        /***********      目标出现      *********/
        if((VisionControlFlag == 1 && VisionControlFlagLast == 0 && enemy_aim_enable[armor_number_no_zero] == 1)){
            state_machine.event_happen(target_detected);
        }


        /***********      目标消失      *********/
        if((VisionControlFlag == 0 && VisionControlFlagLast == 1) && enemy_aim_enable[armor_number_no_zero] == 1){
            state_machine.event_happen(target_disappear);
        }


        /***********      受击      *********/
        if(be_hit_last == 0 && judgeInfo0.be_hit == 1){
            //我真不知道为什么它要自动加8，明明底盘数据是好的
            //0  装甲伤害扣血   5  装甲撞击扣血     都视为受击
            state_machine.event_happen(being_hit);
            be_hit_flag += 1;  //清零在计数任务中
        }

#if MATCH_MODE
        /***********      发弹量达到上限      *********/
        if(judgeInfo2.projectile_allowance_17mm == 0 && projectile_allowance_17mm_last > 0){
            state_machine.event_happen(ammunition_capacity_reached_limit);
            ammunition_depleted = 1;
        }
#else
        /***********      发弹量达到上限      *********/
        if(mains_power_shooter_output_last == 1 && judgeInfo0.mains_power_shooter_output == 0){
            state_machine.event_happen(ammunition_capacity_reached_limit);
            ammunition_depleted = 1;
        }
#endif
        /***********      生命值低下      *********/
        if((float)judgeInfo0.current_HP / (float)judgeInfo1.maximum_HP <= (healed_once == 0 ? 0.3 : 0.5) && (float)last_hp / (float)judgeInfo1.maximum_HP > (healed_once == 0 ? 0.3 : 0.5)){
            state_machine.event_happen(HP_low);
            hp_low = 1;
        }

        /***********      生命值恢复      *********/
        if(judgeInfo0.current_HP == judgeInfo1.maximum_HP && last_hp < judgeInfo0.current_HP && judgeInfo0.game_progress == during_the_match){
            state_machine.event_happen(HP_regeneration);
            hp_low = 0;
            healed_once = 1;
        }

        /***********      前哨站血量低下      *********/
        if(judgeHpInfo.our_outpost_HP <= 400 && our_outpost_HP_last > 400){
            state_machine.event_happen(outpost_HP_low);
        }

        /***********      复活      *********/
        if(judgeInfo0.current_HP == judgeInfo1.maximum_HP && last_hp == 0 && judgeInfo0.game_progress == during_the_match){ //哨兵复活后生命值回满
            state_machine.event_happen(revive);
            dead_once = 1;
        }

        /***********      前哨站被击毁      *********/
#if SERVER_EXIST && OUR_OUTPOST_EXIST
        if(judgeHpInfo.our_outpost_HP == 0 && our_outpost_HP_last > 0){
            outpost_be_destroyed = 1;
            state_machine.event_happen(outpost_destroyed);
        }
#else
        outpost_be_destroyed = 1;
#endif

        /***********      雷达锁定目标      *********/
#if ONLY_HERO
        if(radar_is_reliable_last[hero] == 0 && radar_station_data[hero].is_reliable == 1 && enemy_aim_enable[hero] == 1 && enemy_HP[hero] != 0){
#else
        if((radar_is_reliable_last[hero] == 0 && radar_station_data[hero].is_reliable == 1 && enemy_aim_enable[hero] == 1 && enemy_HP[hero] != 0) ||
                (radar_is_reliable_last[infantry_3] == 0 && radar_station_data[infantry_3].is_reliable == 1 && enemy_aim_enable[infantry_3] == 1 && enemy_HP[infantry_3] != 0) ||
                (radar_is_reliable_last[infantry_4] == 0 && radar_station_data[infantry_4].is_reliable == 1 && enemy_aim_enable[infantry_4] == 1 && enemy_HP[infantry_4] != 0) ||
                (radar_is_reliable_last[infantry_5] == 0 && radar_station_data[infantry_5].is_reliable == 1 && enemy_aim_enable[infantry_5] == 1 && enemy_HP[infantry_5] != 0)){
#endif
            state_machine.event_happen(radar_lock_target);
        }

        /***********      云台手干预     *********/
        if(aerialOperatorData.cmd_keyboard != cmd_keyboard_last){
            state_machine.event_happen(operator_intervene);
        }


        /***********      哨兵前往打击前哨站      *********/
#if SERVER_EXIST && ENEMY_OUTPOST_EXIST && OUR_OUTPOST_EXIST
//        if(judgeInfo0.game_progress == during_the_match && judgeInfo0.stage_remain_time <= attack_outpost_time && stage_remain_time_last > attack_outpost_time
//        && judgeHpInfo.enemy_outpost_HP != 0 && out_patrol_zone_time > LEFT_ATTACK_OUTPOST_PATROL_TIME + 20){
//            state_machine.go_to_specified_state(go_attack_outpost);
//        }
#elif SERVER_EXIST && ENEMY_OUTPOST_EXIST
        if(judgeInfo0.game_progress == during_the_match && judgeInfo0.stage_remain_time <= attack_outpost_time && stage_remain_time_last > attack_outpost_time){
            state_machine.go_to_specified_state(go_attack_outpost);
        }
#endif

        /***********      巡逻区外超时      *********/
        if(out_patrol_zone_time < -10 && dead_once == 0){
            dead_once = 1;
            state_machine.go_to_specified_state(free_defense);
        }


        /***********      约束防守状态及补给状态中状态      *********/
        constrained_defense_state =  late_stage * 1 + insufficient_gold * 2 + time_short * 4 + ammunition_depleted * 8 + hp_low * 16;
        supply_state = insufficient_gold * 1 + hp_low * 2 + ammunition_depleted * 4 + dead_once * 8;
        /***********      变量赋值      *********/
        game_progress_last = judgeInfo0.game_progress;
        g_rc_is_lost_last = g_rc.is_lost;
        VisionControlFlagLast = VisionControlFlag;
        left_is_target_detected_last = twins_receive.is_target_detected;
        be_hit_last = judgeInfo0.be_hit;
        mains_power_shooter_output_last = judgeInfo0.mains_power_shooter_output;
        last_hp = judgeInfo0.current_HP;
        restored_HP_last = restored_HP;
        sw_l_last = g_rc.rc_info.sw.sw_l;
        our_outpost_HP_last = judgeHpInfo.our_outpost_HP;
        stage_remain_time_last = judgeInfo0.stage_remain_time;
        projectile_allowance_17mm_last = judgeInfo2.projectile_allowance_17mm;
        for(int i=0;i<12;i++){
            enemy_HP_last[i] = enemy_HP[i];
        }

        for(int i=0;i<8;i++){
            radar_is_reliable_last[i] = radar_station_data[i].is_reliable;
        }
        cmd_keyboard_last = aerialOperatorData.cmd_keyboard;
        osDelay(1);
    }
}




uint8_t patrol_state = enemy_gathering_point;
uint8_t free_defence_state = our_outpost_defence_zone;
/**
 * 其实主要决策都在底盘运动上
 * 因为无论怎么都在小陀螺
 * 无论怎么两个头都在巡视
 * 所以状态机的最终控制应该都是机器人坐标zeng
 * 但比如在敌方消失在视野里的时候确实可以稍微写一下云台逻辑
 */
void auto_decision_make_task(void *argument) {
    while(robot_data_update != 1){
        osDelay(1);
    }
//    location_init();
    for(;;){
        normal_state = state_machine.get_current_state();
        switch(matchType){
            case debug:     //彩虹楼
                switch(normal_state){
                    /***********      待命状态      *********/
                    case standby:            //自瞄关闭，只自旋和小云台巡逻
                        AimAutoData.AutoAim = 1;
//                        chassis_run();
                        chassis_stop();
                        break;

                    /***********      进攻状态      *********/
                    case attack:
                        AimAutoData.AutoAim = 1;
                        chassis_stop();

                        break;


                    /***********      高优先级寻路状态，此时寻路不会被打断，不会反击      *********/
                    case high_priority_pathfinding:
                        AimAutoData.AutoAim = 0;
                        go_to_target(cooInfo.coo_x, cooInfo.coo_y);
                        if(is_target_point_reach()) {
                            chassis_stop();
                        }
                        break;

                    /***********      中优先级寻路状态，此时寻路不会被打断，会反击      *********/
                    case mid_priority_pathfinding:
                        AimAutoData.AutoAim = 1;
                        go_to_target(cooInfo.coo_x, cooInfo.coo_y);
                        if(is_target_point_reach()) {
                            chassis_stop();
                        }
                        break;

                    /***********      低优先级寻路状态，此时寻路会被打断      *********/
                    case low_priority_pathfinding:
                        AimAutoData.AutoAim = 1;
                        go_to_target(cooInfo.coo_x, cooInfo.coo_y);
                        if(is_target_point_reach()){
                            state_machine.go_to_specified_state(patrol);
                        }

                        break;

                    /***********      巡逻状态      *********/
                    case patrol:
                        AimAutoData.AutoAim = 1;


                        /***********      循环反N字巡逻      *********/
                        switch(patrol_state){
                            case bottom_right_corner:
                                go_to_target(debugLocation[bottom_right_corner].x, debugLocation[bottom_right_corner].y);
                                if(is_target_point_reach()){
                                    patrol_state = top_right_corner;
                                }
                                break;

                            case top_right_corner:
                                go_to_target(debugLocation[top_right_corner].x, debugLocation[top_right_corner].y);
                                if(is_target_point_reach()){
                                    patrol_state = center_point;
                                }
                                break;

                            case center_point:
                                go_to_target(debugLocation[center_point].x, debugLocation[center_point].y);
                                if(is_target_point_reach()){
                                    patrol_state = bottom_left_corner;
                                }
                                break;

                            case bottom_left_corner:
                                go_to_target(debugLocation[bottom_left_corner].x, debugLocation[bottom_left_corner].y);
                                if(is_target_point_reach()){
                                    patrol_state = top_left_corner;
                                }
                                break;

                            case top_left_corner:
                                go_to_target(debugLocation[top_left_corner].x, debugLocation[top_left_corner].y);
                                if(is_target_point_reach()){
                                    patrol_state = bottom_right_corner;
                                }
                                break;


                            default:
                                break;

                        }

                        break;

                    /***********      原地不动防守状态      *********/
                    case stationary_defense:
                        AimAutoData.AutoAim = 1;
                        chassis_stop();

                        break;


                    /***********      小范围移动防守状态      *********/
                    case constrained_defense:
                        AimAutoData.AutoAim = 1;

                        break;


                    case logic:
                        if(state_machine.last_event == HP_low){
                            go_home(debugLocation);
                            state_machine.go_to_specified_state(mid_priority_pathfinding);
                        }

                        if(state_machine.last_event == ammunition_capacity_reached_limit){
                            if(restored_HP < restorable_HP){
                                go_home(debugLocation);
                                state_machine.go_to_specified_state(high_priority_pathfinding);
                            }else{
                                state_machine.go_to_specified_state(patrol);
                            }
                        }

                        break;

                    default:
                        break;
                }


                break;

            case RMUL:
                switch(normal_state){
                    /***********      待命状态      *********/
                    case standby:            //自瞄关闭，只自旋和小云台巡逻
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
                        chassis_stop();

                        break;

                        /***********      进攻状态      *********/
                    case attack:
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
                        chassis_stop();

                        break;


                        /***********      高优先级寻路状态，此时寻路不会被打断，不会反击      *********/
                    case high_priority_pathfinding:
                        go_to_target(cooInfo.coo_x, cooInfo.coo_y);
                        AimAutoData.AutoAim = 0;

                        break;

                        /***********      中优先级寻路状态，此时寻路不会被打断，会反击      *********/
                    case mid_priority_pathfinding:
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
                        if(is_target_point_reach()) {
                            chassis_stop();
                        }
                        break;

                        /***********      低优先级寻路状态，此时寻路会被打断      *********/
                    case low_priority_pathfinding:
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
                        go_to_target(closest_coo_to_target(enemyCoo.x, enemyCoo.y, RMUL_location, LOCATION_NUM).x, closest_coo_to_target(enemyCoo.x, enemyCoo.y, RMUL_location, LOCATION_NUM).y);
                        if(is_target_point_reach()){
                            go_to_target(RMUL_location[radical_point].x, RMUL_location[radical_point].y);
                        }

                        break;

                        /***********      巡逻状态      *********/
                    case patrol:
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;


                        /***********      前压三点巡逻      *********/
                        switch(patrol_state){
                            case radical_point:
                                go_to_target(RMUL_location[radical_point].x, RMUL_location[radical_point].y);
                                if(is_target_point_reach()){
                                    patrol_state = center_point;
                                }
                                break;

                            case center_point:
                                go_to_target(RMUL_location[center_point].x, RMUL_location[center_point].y);
                                if(is_target_point_reach()){
                                    patrol_state = conservative_point;
                                }
                                break;

                            case conservative_point:
                                go_to_target(RMUL_location[conservative_point].x, RMUL_location[conservative_point].y);
                                if(is_target_point_reach()){
                                    patrol_state = radical_point;
                                }
                                break;

                            default:
                                break;

                        }

                        break;

                        /***********      原地不动防守状态      *********/
                    case stationary_defense:
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
                        chassis_stop();

                        break;


                        /***********      小范围移动防守状态      *********/
                    case constrained_defense:
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;

                        break;


                    case logic:
                        if(state_machine.last_event == HP_low){
                            go_home(RMUL_location);
                            state_machine.go_to_specified_state(mid_priority_pathfinding);
                        }

                        if(state_machine.last_event == ammunition_capacity_reached_limit){
                            if(restored_HP < restorable_HP){
                                go_home(RMUL_location);
                                state_machine.go_to_specified_state(high_priority_pathfinding);
                            }else{
                                state_machine.go_to_specified_state(patrol);
                            }
                        }

                        if(state_machine.last_event == match_begin || state_machine.last_event == turn_on_auto){
                            go_to_target(RMUL_location[conservative_point].x, RMUL_location[conservative_point].y);
                            state_machine.go_to_specified_state(mid_priority_pathfinding);
                        }

                        if(state_machine.last_event == HP_regeneration){
                            go_to_target(RMUL_location[initial_point].x, RMUL_location[initial_point].y);
                            state_machine.go_to_specified_state(mid_priority_pathfinding);
                        }

                        break;

                    default:
                        break;
                }
                break;

            case RMUC:
                switch(normal_state){
                    /***********      待命状态      *********/
                    case standby:            //自瞄关闭，只自旋和小云台巡逻
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
//#if MATCH_MODE
//                        if(judgeInfo0.game_progress == during_the_match){       //防止晚开自动模式
//                            state_machine.go_to_specified_state(patrol);
//                            break;
//                        }
//#endif

                        chassis_stop();
                        break;

                        /***********      进攻状态      *********/
                    case attack:
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
                        if(VisionControlFlag == 1){
                            go_attack_enemy();
                        }else{
                            state_machine.go_to_specified_state(dead_once == 1 ? free_defense : patrol);
                        }

                        break;


                        /***********      高优先级寻路状态，此时寻路不会被打断，不会反击      *********/
                    case high_priority_pathfinding:         //目前只有死亡复活后会进入这个状态
                        AimAutoData.AutoAim = 0;
                        go_to_target(cooInfo.coo_x, cooInfo.coo_y);
                        if(is_target_point_reach() && dead_once == 1 && judgeInfo0.is_occupy_healing_spot == 1){
                            state_machine.go_to_specified_state(free_defense);
                        }

                        break;

                        /***********      中优先级寻路状态，此时寻路不会被打断，会反击      *********/
                    case mid_priority_pathfinding:
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
                        go_to_target(cooInfo.coo_x, cooInfo.coo_y);

                        break;

                        /***********      低优先级寻路状态，此时寻路会被打断      *********/
                    case low_priority_pathfinding:
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
                        go_to_target(cooInfo.coo_x, cooInfo.coo_y);

                        break;

                        /***********      巡逻状态      *********/
                    case patrol:
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;

                        /***********      前压三点巡逻      *********/

                        if((out_patrol_zone_time <= SENTRY_GO_BACK_TIME || (judgeInfo0.current_HP <= 300 && healed_once == 0) || (healed_once == 1 && outpost_be_destroyed == 1))
                        || radarInfo.is_not_patrol == 1){
                            state_machine.go_to_specified_state(constrained_defense);
                            break;
                        }

                        switch(patrol_state){
                            case enemy_gathering_point:
                                go_to_target(RMUC_location[enemy_gathering_point].x, RMUC_location[enemy_gathering_point].y);
                                if(is_target_point_reach()){
                                    patrol_state = enemy_base_entrance;
                                }
                                sentry_destination = enemy_gathering_point;
                                break;

                            case enemy_base_entrance:
                                go_to_target(RMUC_location[enemy_base_entrance].x, RMUC_location[enemy_base_entrance].y);
                                if(is_target_point_reach()){
                                    patrol_state = enemy_R1_entrance;
                                }
                                sentry_destination = enemy_R1_entrance;
                                break;

                            case enemy_R1_entrance:
                                go_to_target(RMUC_location[enemy_R1_entrance].x, RMUC_location[enemy_R1_entrance].y);
                                if(is_target_point_reach()){
                                    patrol_state = enemy_gathering_point;
                                }
                                sentry_destination = enemy_gathering_point;
                                break;

                            default:
                                break;

                        }



                        break;

                        /***********      原地不动防守状态      *********/
                    case stationary_defense:
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
                        sentry_destination = 0;
                        chassis_stop();

                        break;


                        /***********      约束防守状态      *********/
                    case constrained_defense:
                        /**
                         * 这里一共有四个因素
                         * 1. 是否血量低下
                         * 2. 是否弹丸打完
                         * 3. 巡逻区外剩余时间
                         * 4. 金币是否充裕
                         * 分开讨论，用if else写出16种情况
                         * case情况参照obsidian技术文档，但其实也就是上述条件编码成二进制
                         */
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
                        if((out_patrol_zone_time > SENTRY_GO_BACK_TIME && ((judgeInfo0.current_HP > 300 && healed_once == 0) || (judgeInfo0.current_HP > 300 && healed_once == 1 && outpost_be_destroyed == 0)) && judgeInfo2.projectile_allowance_17mm > 0)
                        && radarInfo.is_not_patrol == 0){
                            state_machine.go_to_specified_state(patrol);
                            break;
                        }

                        if(normal_state_last != constrained_defense){       //防止从supply状态过来兑换请求未清零
                            exchange_ammo_request = 0;
                        }

                        if(constrained_defense_state != constrained_defense_state_last){        //防止从状态变换兑换请求未清零
                            exchange_ammo_request = 0;
                        }
                        switch(constrained_defense_state){
                            case 0:
                                if((hp_full == 1 && healed_once == 0 && healing_spot_ammo_accumulation > 0) || (healing_spot_ammo_accumulation >= 200 && healed_once == 1)){
                                    go_to_constrained_zone(healing_point);
                                }else{
                                    go_to_constrained_zone(our_R3_patrol_zone);
                                }
                                break;
                            case 1:
                                if((hp_full == 1 && healed_once == 0 && healing_spot_ammo_accumulation > 0) || (healing_spot_ammo_accumulation >= 200 && healed_once == 1)){
                                    go_to_constrained_zone(healing_point);
                                }else{
                                    go_to_constrained_zone(our_base_patrol_zone);
                                }
                                break;
                            case 2:
                                if((hp_full == 1 && healed_once == 0 && healing_spot_ammo_accumulation > 0) || (healing_spot_ammo_accumulation >= 200 && healed_once == 1)){
                                    go_to_constrained_zone(healing_point);
                                }else{
                                    go_to_constrained_zone(our_R3_patrol_zone);
                                }
                                break;
                            case 3:
                                if((hp_full == 1 && healed_once == 0 && healing_spot_ammo_accumulation > 0) || (healing_spot_ammo_accumulation >= 200 && healed_once == 1)){
                                    go_to_constrained_zone(healing_point);
                                }else{
                                    go_to_constrained_zone(our_base_patrol_zone);
                                }
                                break;
                            case 4:
                                go_to_constrained_zone(our_base_patrol_zone);
                                break;
                            case 5:
                                if(out_patrol_zone_time > 10){
                                    if((hp_full == 1 && healed_once == 0 && healing_spot_ammo_accumulation > 0) || (healing_spot_ammo_accumulation >= 200 && healed_once == 1)){
                                        go_to_constrained_zone(healing_point);
                                    }else{
                                        go_to_constrained_zone(our_base_patrol_zone);
                                    }
                                }else{
                                    go_to_constrained_zone(our_base_patrol_zone);
                                }
                                break;
                            case 6:
                                go_to_constrained_zone(our_base_patrol_zone);
                                break;
                            case 7:
                                if(out_patrol_zone_time > 10){
                                    if((hp_full == 1 && healed_once == 0 && healing_spot_ammo_accumulation > 0) || (healing_spot_ammo_accumulation >= 200 && healed_once == 1)){
                                        go_to_constrained_zone(healing_point);
                                    }else{
                                        go_to_constrained_zone(our_base_patrol_zone);
                                    }
                                }else{
                                    go_to_constrained_zone(our_base_patrol_zone);
                                }
                                break;
                            case 8:
                                if(healing_spot_ammo_accumulation > 0 && (healed_once == 1 || (hp_full == 1 && healed_once == 0))){
                                    go_to_constrained_zone(healing_point);
                                }else{
                                    go_to_constrained_zone(our_R3_patrol_zone);
                                    remote_exchange_ammo_request = (constrained_defense_state != constrained_defense_state_last || normal_state != normal_state_last) ? 1 : remote_exchange_ammo_request;
                                }
                                break;
                            case 9:
                                if(healing_spot_ammo_accumulation > 0 && (healed_once == 1 || (hp_full == 1 && healed_once == 0))){
                                    go_to_constrained_zone(healing_point);
                                }else{
                                    go_to_constrained_zone(our_base_patrol_zone);
                                }
                                break;
                            case 10:
                                if(healing_spot_ammo_accumulation > 0 && (healed_once == 1 || (hp_full == 1 && healed_once == 0))){
                                    go_to_constrained_zone(healing_point);
                                }else{
                                    go_to_constrained_zone(our_R3_patrol_zone);
                                }
                                break;
                            case 11:
                                if(healing_spot_ammo_accumulation > 0 && (healed_once == 1 || (hp_full == 1 && healed_once == 0))){
                                    go_to_constrained_zone(healing_point);
                                }else{
                                    go_to_constrained_zone(our_base_patrol_zone);
                                }
                                break;
                            case 12:
                                go_to_constrained_zone(our_base_patrol_zone);
                                break;
                            case 13:
                                if(out_patrol_zone_time > 10){
                                    if(healing_spot_ammo_accumulation > 0 && (healed_once == 1 || (hp_full == 1 && healed_once == 0))){
                                        go_to_constrained_zone(healing_point);
                                    }else{
                                        go_to_constrained_zone(our_base_patrol_zone);
                                        remote_exchange_ammo_request = (constrained_defense_state != constrained_defense_state_last || normal_state != normal_state_last) ? 1 : remote_exchange_ammo_request;
                                    }
                                }else{
                                    go_to_constrained_zone(our_base_patrol_zone);
                                }
                                break;
                            case 14:
                                go_to_constrained_zone(our_base_patrol_zone);
                                break;
                            case 15:
                                if(out_patrol_zone_time > 10){
                                    if((hp_full == 1 && healed_once == 0 && healing_spot_ammo_accumulation > 0) || (healing_spot_ammo_accumulation >= 200 && healed_once == 1)){
                                        go_to_constrained_zone(healing_point);
                                    }else{
                                        go_to_constrained_zone(our_base_patrol_zone);
                                    }
                                }else{
                                    go_to_constrained_zone(our_base_patrol_zone);
                                }
                                break;
                            case 16:
                                go_to_constrained_zone(healing_point);
                                break;
                            case 17:
                                go_to_constrained_zone(healing_point);
                                break;
                            case 18:
                                go_to_constrained_zone(healing_point);
                                break;
                            case 19:
                                go_to_constrained_zone(healing_point);
                                break;
                            case 20:
                                go_to_constrained_zone(our_base_patrol_zone);
                                break;
                            case 21:
                                if(out_patrol_zone_time > 10){
                                    go_to_constrained_zone(healing_point);
                                }else{
                                    go_to_constrained_zone(our_base_patrol_zone);
                                }
                                break;
                            case 22:
                                go_to_constrained_zone(our_base_patrol_zone);
                                break;
                            case 23:
                                if(out_patrol_zone_time > 10){
                                    go_to_constrained_zone(healing_point);
                                }else{
                                    go_to_constrained_zone(our_base_patrol_zone);
                                }
                                break;
                            case 24:
                                go_to_constrained_zone(healing_point);
                                if(healing_spot_ammo_accumulation == 0){
                                    if(constrained_defense_state != constrained_defense_state_last || normal_state != normal_state_last){
                                        exchange_ammo_request = 1;
                                    }
                                }else{
                                    exchange_ammo_request = 0;
                                }
                                break;
                            case 25:
                                go_to_constrained_zone(healing_point);
                                if(healing_spot_ammo_accumulation == 0){
                                    if(constrained_defense_state != constrained_defense_state_last || normal_state != normal_state_last){
                                        exchange_ammo_request = 1;
                                    }
                                }else{
                                    exchange_ammo_request = 0;
                                }
                                break;
                            case 26:
                                go_to_constrained_zone(healing_point);
                                break;
                            case 27:
                                go_to_constrained_zone(healing_point);
                                break;
                            case 28:
                                if(out_patrol_zone_time > 10){
                                    go_to_constrained_zone(healing_point);
                                    if(healing_spot_ammo_accumulation == 0){
                                        if(constrained_defense_state != constrained_defense_state_last || normal_state != normal_state_last){
                                            exchange_ammo_request = 1;
                                        }
                                    }else{
                                        exchange_ammo_request = 0;
                                    }
                                }else{
                                    go_to_constrained_zone(our_base_patrol_zone);
                                }
                                break;
                            case 29:
                                if(out_patrol_zone_time > 10){
                                    go_to_constrained_zone(healing_point);
                                    if(healing_spot_ammo_accumulation == 0){
                                        if(constrained_defense_state != constrained_defense_state_last || normal_state != normal_state_last){
                                            exchange_ammo_request = 1;
                                        }
                                    }else{
                                        exchange_ammo_request = 0;
                                    }
                                }else{
                                    go_to_constrained_zone(our_base_patrol_zone);
                                }
                                break;
                            case 30:
                                go_to_constrained_zone(our_base_patrol_zone);
                                break;
                            case 31:
                                if(out_patrol_zone_time > 10){
                                    go_to_constrained_zone(healing_point);
                                }else{
                                    go_to_constrained_zone(our_base_patrol_zone);
                                }
                                break;
                            default:
                                go_to_constrained_zone(our_base_patrol_zone);
                                break;
                        }


                        constrained_defense_state_last = constrained_defense_state;
                        break;


                    case logic:
                        if(state_machine.last_event == revive){
                            go_home(RMUC_location);
                            state_machine.go_to_specified_state(high_priority_pathfinding);
                            sentry_destination = healing_point;
//                            state_machine.go_to_specified_state(patrol);      //调试用


                        }else if(state_machine.last_event == radar_lock_target){    //只响应英雄跟步兵
#if ONLY_HERO
                            if(radar_station_data[hero].is_reliable == 1){
                                enemyCoo.x = radar_station_data[hero].x;
                                enemyCoo.y = radar_station_data[hero].y;
                                state_machine.go_to_specified_state(pursuit);
                            }
#else
                            if(radar_station_data[hero].is_reliable == 1){
                                enemyCoo.x = radar_station_data[hero].x;
                                enemyCoo.y = radar_station_data[hero].y;
                                state_machine.go_to_specified_state(pursuit);
                            }else if(radar_station_data[infantry_3].is_reliable == 1){
                                enemyCoo.x = radar_station_data[infantry_3].x;
                                enemyCoo.y = radar_station_data[infantry_3].y;
                                state_machine.go_to_specified_state(pursuit);
                            }else if(radar_station_data[infantry_4].is_reliable == 1){
                                enemyCoo.x = radar_station_data[infantry_4].x;
                                enemyCoo.y = radar_station_data[infantry_4].y;
                                state_machine.go_to_specified_state(pursuit);
                            }else if(radar_station_data[infantry_5].is_reliable == 1){
                                enemyCoo.x = radar_station_data[infantry_5].x;
                                enemyCoo.y = radar_station_data[infantry_5].y;
                                state_machine.go_to_specified_state(pursuit);
                            }
#endif
                            else{
                                evaluate_and_return_from_supply_state();        //应该不会到这里，双重保障
                            }


                        }else if(state_machine.last_event == operator_intervene){
                            if(aerialOperatorData.cmd_keyboard == cmd_B){
                                state_machine.go_to_specified_state(error);
                            }
                        }

                        break;

                    case pursuit:
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
                        sentry_destination = 0;
                        if(pursuit_time >= 10){
                            state_machine.go_to_specified_state(dead_once == 1 ? free_defense : patrol);
                        }

#if SERVER_EXIST

                        if(enemy_HP[armor_number_no_zero] != 0){

                            go_to_target(enemyCoo.x, enemyCoo.y);
                            if(is_target_point_reach()){
                                state_machine.go_to_specified_state(dead_once == 1 ? free_defense : patrol);
                            }
                        }else{
                            state_machine.go_to_specified_state(dead_once == 1 ? free_defense : patrol);
                        }

#else
                        go_to_target(enemyCoo.x, enemyCoo.y);
                            if(is_target_point_reach()){
                                state_machine.go_to_specified_state(dead_once == 1 ? free_defense : patrol);
                            }
#endif

                        break;

                    case free_defense:
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
                        switch(free_defence_state){
                            case our_outpost_defence_zone:
                                go_to_target(RMUC_location[our_outpost_defence_zone].x, RMUC_location[our_outpost_defence_zone].y);
                                if(is_target_point_reach()){
                                    free_defence_state = our_bridge_tunnel_entrance;
                                }
                                sentry_destination = our_outpost_defence_zone;
                                break;

                            case our_bridge_tunnel_entrance:
                                go_to_target(RMUC_location[our_bridge_tunnel_entrance].x, RMUC_location[our_bridge_tunnel_entrance].y);
                                if(is_target_point_reach()){
                                    free_defence_state = our_R1_entrance;
                                }
                                sentry_destination = our_bridge_tunnel_entrance;
                                break;

                            case our_R1_entrance:
                                go_to_target(RMUC_location[our_R1_entrance].x, RMUC_location[our_R1_entrance].y);
                                if(is_target_point_reach()){
                                    free_defence_state = our_outpost_defence_zone;
                                }
                                sentry_destination = our_R1_entrance;
                                break;

                            default:
                                break;

                        }

                        break;


                    case supply:
                        /**
                         * 这里一共有四个因素
                         * 1. 是否已死亡过
                         * 1. 是否血量低下
                         * 2. 是否弹丸打完
                         * 3. 金币是否充裕
                         * 分开讨论，用if else写出16种情况
                         * case情况参照上述条件编码成二进制
                         * supply_state = insufficient_gold * 1 + ammunition_depleted * 2 + hp_low * 4 + dead_once * 8;
                         */
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
                        switch(supply_state){
                            case 0:
                                evaluate_and_return_from_supply_state();
                                break;
                            case 1:
                                evaluate_and_return_from_supply_state();
                                break;
                            case 2:
                                go_home(RMUC_location);
                                break;
                            case 3:
                                go_home(RMUC_location);
                                break;
                            case 4:
                                if(healing_spot_ammo_accumulation > 0 && (healed_once == 1 || (hp_full == 1 && healed_once == 0))){
                                    go_home(RMUC_location);
                                }else{
                                    remote_exchange_ammo_request = (supply_state != supply_state_last || normal_state != normal_state_last) ? 1 : remote_exchange_ammo_request;
                                    evaluate_and_return_from_supply_state();
                                }
                                break;
                            case 5:
                                if(healing_spot_ammo_accumulation > 0 && (healed_once == 1 || (hp_full == 1 && healed_once == 0))){
                                    go_home(RMUC_location);
                                }else{
                                    if(judgeInfo0.stage_remain_time > 280 && judgeInfo0.game_progress == during_the_match){
                                        go_to_target(RMUC_location[our_base_patrol_zone].x, RMUC_location[our_base_patrol_zone].y);
                                        sentry_destination = our_base_patrol_zone;
                                    }else{
                                        go_home(RMUC_location);
                                    }
                                }
                                break;
                            case 6:
                                go_home(RMUC_location);
                                break;
                            case 7:
                                go_home(RMUC_location);
                                break;
                            case 8:
                                evaluate_and_return_from_supply_state();
                                break;
                            case 9:
                                evaluate_and_return_from_supply_state();
                                break;
                            case 10:
                                go_home(RMUC_location);
                                break;
                            case 11:
                                go_home(RMUC_location);
                                break;
                            case 12:
                                go_home(RMUC_location);
                                if(healing_spot_ammo_accumulation == 0){
//                                    exchange_ammo_request = (supply_state != supply_state_last || normal_state != normal_state_last) ? 1 : exchange_ammo_request;
                                }
                                break;
                            case 13:
                                go_home(RMUC_location);
                                if(healing_spot_ammo_accumulation == 0){
//                                    exchange_ammo_request = (supply_state != supply_state_last || normal_state != normal_state_last) ? 1 : exchange_ammo_request;
                                }
                                break;
                            case 14:
                                go_home(RMUC_location);
                                break;
                            case 15:
                                go_home(RMUC_location);
                                break;
                            default:
                                go_to_target(RMUC_location[our_base_patrol_zone].x, RMUC_location[our_base_patrol_zone].y);
                                sentry_destination = our_base_patrol_zone;
                                break;
                        }
                        supply_state_last = supply_state;

                        break;

                    case go_attack_outpost:
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
                        go_to_target(RMUC_location[enemy_outpost_impact_point].x, RMUC_location[enemy_outpost_impact_point].y);
                        sentry_destination = enemy_outpost_impact_point;
#if GO_ATTACK_OUTPOST_DEBUG
#else
                        if(judgeHpInfo.enemy_outpost_HP == 0 || outpost_fire_cnt >= OUTPOST_AMMUNITION_CAPACITY || out_patrol_zone_time < LEFT_ATTACK_OUTPOST_PATROL_TIME){
                            state_machine.go_to_specified_state(patrol);
                        }
#endif


                        break;


                    case error:
                        AimAutoData.AutoAim = judgeInfo0.current_HP == 0 ? 0 : 1;
                        go_to_constrained_zone(our_base_patrol_zone);
                        break;

                    default:
                        break;
                }


                break;
        }
        is_occupy_healing_spot_last = judgeInfo0.is_occupy_healing_spot;
        normal_state_last = state_machine.get_current_state();
        normal_event = state_machine.last_event;
        osDelay(1);
    }
}


